﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using Microsoft.Win32;

namespace GypeLaunch
{
    public partial class Form1 : Form
    {
        IntPtr mLastWindow = IntPtr.Zero;
        Process mLastProcess = null;


        public Form1()
        {
            Process.EnterDebugMode();
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //timer.Enabled = !timer.Enabled;

            Process.EnterDebugMode();

            ChooseProcessDialog dlg = new ChooseProcessDialog();
            dlg.ShowDialog();

            if (dlg.ChosenProcess == -1)
                return;
            var process = Process.GetProcessById(dlg.ChosenProcess);


            UnloadPreviousProcess();
            LoadIntoProcess(process);

            mLastProcess = process;
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            var currentWindow = Win32.GetForegroundWindow();

            if (mLastWindow == currentWindow)
                return;

            int processId;
            Win32.GetWindowThreadProcessId(currentWindow, out processId);

            var process = Process.GetProcessById(processId);

            if (!IsGame(process))
                return;

            //UnloadPreviousProcess();
            LoadIntoProcess(process);

            mLastWindow = currentWindow;
        }

        private bool IsGame(Process process)
        {
            foreach(ProcessModule module in process.Modules)
            {
                if (module.ModuleName.Contains("D3D"))
                    return true;
            }

            return false;
        }

        /// TODO: Rename me!
        private void GetInjectorPaths(Process process, out string dllName, out string exeName)
        {
            dllName = exeName = Directory.GetCurrentDirectory();
            if (Environment.Is64BitOperatingSystem)
            {
                bool isWow64Process;
                Win32.IsWow64Process(process.Handle, out isWow64Process);

                if (isWow64Process)
                {
                    dllName += "\\Gype_x86.dll";
                    exeName += "\\GypeInject_x86";
                }
                else
                {
                    dllName += "\\Gype_x64.dll";
                    exeName += "\\GypeInject_x64";
                }
            }
            else
            {
                dllName += "\\Gype_x86.dll";
                exeName += "\\GypeInject_x86";
            }
        }

        private void LoadIntoProcess(Process process)
        {
            string exePath;
            string dllPath;

            GetInjectorPaths(process, out dllPath, out exePath);

            Process injector = new Process();
            var args = String.Format("-i {0} {1}", dllPath, process.Id);
            injector.StartInfo = new ProcessStartInfo(exePath, args);
            injector.Start();
        }

        private void UnloadPreviousProcess()
        {
            if (mLastProcess == null)
                return;

            string exePath;
            string dllPath;

            GetInjectorPaths(mLastProcess, out dllPath, out exePath);

            Process injector = new Process();
            var args = String.Format("-e {0} {1}", dllPath, mLastProcess.Id);
            injector.StartInfo = new ProcessStartInfo(exePath, args);
            injector.Start();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var hkey = Registry.CurrentUser.OpenSubKey("Software\\Gype\\", true);
            if (hkey == null)
                hkey = Registry.CurrentUser.CreateSubKey("Software\\Gype\\", RegistryKeyPermissionCheck.ReadWriteSubTree);

            var currentDir = Directory.GetCurrentDirectory();

            string path = (string)hkey.GetValue("InstallDir");
            if (path == null || path != currentDir)
                hkey.SetValue("InstallDir", currentDir);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //UnloadPreviousProcess();
        }
    }
}
